﻿using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Reflection;
using EPiServer.Core;

namespace OpenWaves.EPiServer
{
    public static class BuiltInProperties
    {
        public const string ArchiveLink = "PageArchiveLink";
        public const string Category = "PageCategory";
        public const string Changed = "PageChanged";
        public const string ChangedBy = "PageChangedBy";
        public const string Created = "PageCreated";
        public const string CreatedBy = "PageCreatedBy";
        public const string Deleted = "PageDeleted";
        public const string LanguageBranch = "PageLanguageBranch";
        public const string LinkType = "PageShortcutType";
        [SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "URL")]
        public const string LinkURL = "PageLinkURL";
        public const string MasterLanguageBranch = "PageMasterLanguageBranch";
        public const string PageGuid = "PageGUID";
        public const string PageLink = "PageLink";
        public const string PageName = "PageName";
        [SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "ID")]
        public const string PageTypeID = "PageTypeID";
        public const string PageTypeName = "PageTypeName";
        public const string ParentLink = "PageParentLink";
        public const string StartPublish = "PageStartPublish";
        public const string Status = "PageWorkStatus";
        public const string StopPublish = "PageStopPublish";
        [SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "URL")]
        public const string URLSegment = "PageURLSegment";
        public const string VisibleInMenu = "PageVisibleInMenu";
        public const string HasTemplate = "HasTemplate";

        private static readonly IEnumerable<string> propertyNames = InitalizePropertyNames();

        private static IEnumerable<string> InitalizePropertyNames()
        {
            var constantFields = typeof(BuiltInProperties)
                .GetFields(BindingFlags.Static | BindingFlags.Public)
                .Where(f => f.IsLiteral && f.FieldType == typeof(string));

            return constantFields
                .Select(f => (string) f.GetValue(null))
                .ToList();
        }

        public static IEnumerable<string> All
        {
            get { return propertyNames; }
        }

        public static bool Contains(string propertyName)
        {
            return propertyNames.Contains(propertyName);
        }

        [SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity")]
        public static object GetValue(string propertyName, PageData pageData)
        {
            switch (propertyName)
            {
                case ArchiveLink:
                    return pageData.ArchiveLink;
                case Category:
                    return pageData.Category;
                case Changed:
                    return pageData.Changed;
                case ChangedBy:
                    return pageData.ChangedBy;
                case Created:
                    return pageData.Created;
                case CreatedBy:
                    return pageData.CreatedBy;
                case Deleted:
                    return pageData.IsDeleted;
                case LanguageBranch:
                    return pageData.LanguageBranch;
                case LinkType:
                    return pageData.LinkType;
                case LinkURL:
                    return pageData.LinkURL;
                case MasterLanguageBranch:
                    return pageData.MasterLanguageBranch;
                case PageGuid:
                    return pageData.PageGuid;
                case PageLink:
                    return pageData.PageLink;
                case PageName:
                    return pageData.PageName;
                case PageTypeID:
                    return pageData.PageTypeID;
                case PageTypeName:
                    return pageData.PageTypeName;
                case ParentLink:
                    return pageData.ParentLink;
                case StartPublish:
                    return pageData.StartPublish;
                case Status:
                    return pageData.Status;
                case StopPublish:
                    return pageData.StopPublish;
                case URLSegment:
                    return pageData.URLSegment;
                case VisibleInMenu:
                    return pageData.VisibleInMenu;
                case HasTemplate:
                    return pageData.HasTemplate;
                default:
                    throw new ArgumentException(ExceptionMessage.Format("Built in property '{0}' not found.", propertyName), "propertyName");
            }
        }
    }
}